home *** CD-ROM | disk | FTP | other *** search
- /*
- * The original copyright owners of the accompanying source code files have
- * agreed to place such code into the public domain. Accordingly, anyone
- * who receives or obtains a copy of such source code is freely entitled to
- * reproduce, use and otherwise exploit such code (including the right to
- * make derivative works), at his/her own risk and expense, without any
- * obligation or liability to the original copyright owners.
- *
- * We would appreciate (but do not require) that the following message be
- * included in any derivative works:
- *
- * "Portions of this program were developed by Peter Broadwell, Rob Myers
- * and Robin Schaufler while working in Silicon Valley."
- *
- * The accompanying source code files and related documentation materials
- * are distributed on an "AS IS" basis, without any warranties or
- * guarantees of any kind. All implied warranties, including the implied
- * warranties of merchantability and of fitness for any particular purpose,
- * are expressly disclaimed.
- */
- #include <stdlib.h>
- #include <stdio.h>
- #include <math.h>
- #include <gl.h>
- #include <device.h>
-
- #include "geom.h"
- #include "selectors.h"
- #include "class.h"
- #include "classIds.h"
- #include "mbox.h"
- #include "individual.h"
- #include "panel.h"
- #include "behavior.h"
- #include "doers.h"
- #include "colors.h"
- #include "voxel.h"
-
- #include "camera.h"
- #include "sea.h"
- #include "toad.h"
- #include "pebbles.h"
- #include "egg.h"
-
- #include "sys/types.h"
- #include "timeb.h"
-
- extern struct timeb tb_start, tb_end; /* timer blocks */
-
- #define PI 3.14159265358979323844
- #define DEG(x) ((float)x*(float)180/PI)
- #define RAD(x) ((float)x*PI/(float)180)
-
- extern unsigned short scaleyTex1[];
- extern unsigned short spottyTex2[];
-
- extern individual usTemplate;
- extern individual indivTemplate;
- extern individual minnowTemplate;
- extern individual guppyTemplate;
- extern individual bubbleMachineTemplate;
- extern individual eggTemplate;
- extern wiggler wigglerTemplate;
- extern behavior circlerTemplate;
- extern behavior swerverTemplate;
- extern behavior chameleonTemplate;
- extern behavior colorizerTemplate;
- extern behavior advancerTemplate;
- extern behavior expanderTemplate;
- extern behavior surfDieTemplate;
- extern behavior metamorphTemplate;
- extern behavior maleTemplate;
- extern behavior femaleTemplate;
- extern behavior feederTemplate;
- extern behavior wideyeTemplate;
- extern behavior trailGhostTemplate;
- extern behavior faderTemplate;
- extern camera cameraTemplate;
- extern sea seaTemplate;
- extern toad toadTemplate;
- extern pebbles pebbleTemplate;
- extern mailbox fullVoxels;
- extern masterPanel mPanelTemplate;
-
- extern char frozen;
- extern char dobackground;
- extern char bullet;
- extern char timeit;
- extern char quit;
- extern voxel *bigBang();
- extern inst* clone();
- int doingRGB = 0;
-
- individual *us;
- camera *theCamera;
- masterPanel *thePanel;
- voxel *universe;
- point univol = {10000, 10000, 10000};
- point voxvol = {1000, 1000, 1000};
- point bowlRadius = {4000, 4000, 4000};
- long masterClock = 0;
- long saveClock = 0;
- long newClock = 0;
- long fishPop = 0;
- long numgups;
- int unsophistication = 98;
- point2d curWindow;
- point2df scalePanel;
-
- int landscape = TRUE; /* put in the seaweed and pebles */
- int egg_flag = TRUE; /* should sexual reproduction take place */
- int bub_flag = TRUE; /* should there be any bubles */
- int feed_flag = TRUE; /* should they try and eat each other */
- int toad_flag = FALSE; /* is there a toad on the floor - doesn't work yet */
- int ghost_flag = FALSE; /* attempt at making trails - doesn't work yet */
- int video_flag = FALSE; /* should be video sized with large cursor */
- int controls = TRUE; /* show controls by default */
- int allbuttons = TRUE; /* make all mouse buttons behave the same */
- int maldbug = FALSE; /* enable malloc debuging - only with FUNNY_MALLOC */
- int dumper = FALSE; /* be noisy and print subscriber lists */
- int (*subscrFcn)();
- extern subscribe(), halfsubscr();
-
- Cursor arrow = {
- 0x8080,
- 0xc1c0,
- 0xe3e0,
- 0xf7f0,
- 0xfff8,
- 0xfffc,
- 0xfffe,
- 0xffff,
- 0xfffe,
- 0xfffc,
- 0xfff8,
- 0xfff0,
- 0xfff8,
- 0xfffc,
- 0xfffe,
- 0xffff,
- };
-
- main(argc,argv,envp)
- int argc;
- char *argv[], **envp;
- {
- int c;
- int errflg = 0;
-
- while ((c = getopt(argc, argv, "bceflmv")) != -1) {
- switch (c) {
- /*
- case 'a':
- allbuttons = !allbuttons;
- break;
- */
- case 'b':
- bub_flag = !bub_flag;
- break;
- case 'c':
- controls = !controls;
- break;
- /*
- case 'd':
- dumper = !dumper;
- break;
- */
- case 'e':
- egg_flag = !egg_flag;
- break;
- case 'f':
- feed_flag = !feed_flag;
- break;
- /*
- case 'g':
- ghost_flag = !ghost_flag;
- break;
- */
- case 'l':
- landscape = !landscape;
- break;
- case 'm':
- maldbug = !maldbug;
- break;
- case 'v':
- video_flag = !video_flag;
- break;
- /*
- case 't':
- toad_flag = !toad_flag;
- break;
- */
- default:
- usage();
- break;
- }
- }
- if (errflg) {
- usage();
- }
-
- if (egg_flag) {
- subscrFcn = halfsubscr;
- } else {
- subscrFcn = subscribe;
- }
-
- setup(video_flag);
- tic();
- system("/usr/sbin/makemap");
- gexit();
- }
-
-
- usage()
- {
- fprintf(stderr,"usage: gold [-bceflmv]\n");
- fprintf(stderr," -b don't display the bubbles visible by default\n");
- fprintf(stderr," -c don't show the controls visible by default\n");
- fprintf(stderr," -e prevent sexual reproduction from taking place\n");
- fprintf(stderr," -f keep fish from eating each other (mightn't work--old debug cruft)\n");
- fprintf(stderr," -l don't display the landscape visible by default\n");
- fprintf(stderr," -m enable's malloc debugging\n");
- fprintf(stderr," -v open as 640x480 NTSC video-sized window w/large cursor\n");
- }
-
- /*
- * setup the fishbowl parameters for E-Z viewing pleasure
- */
- setup(vidp)
- {
- foreground();
-
- if(!vidp)
- prefposition(0,getgdesc(GD_XPMAX),0,getgdesc(GD_YPMAX));
- else
- prefposition(0,640, 0,480);
- winopen("gold");
- getsize(&curWindow.x, &curWindow.y);
- if(vidp) {
- defcursor(1,arrow);
- curorigin(1,0,16);
- setcursor(1,0,0);
- }
- winattach();
-
- /* set scaling of control Panel viewport to WC */
- scalePanel.x = 256.0 / (float)(curWindow.x - curWindow.y);
- scalePanel.y = 767.0 / (float)curWindow.y;
-
- setdepth(-20000,20000);
- qdevice(BKEY);
- qdevice(FKEY);
- qdevice(QKEY);
- qdevice(SKEY);
- qdevice(ZKEY);
- qdevice(ESCKEY);
- qdevice(VIRGULEKEY);
- qdevice(LEFTMOUSE);
- qdevice(MIDDLEMOUSE);
- qdevice(RIGHTMOUSE);
-
- backface(TRUE);
- picksize(1,1);
- defpattern(SCALEY_TEX1, 16, scaleyTex1);
- defpattern(SPOTTY_TEX2, 16, spottyTex2);
- setColorMap();
- fishColor(WATER_COLOR);
- clear();
- doublebuffer();
- drawmode(NORMALDRAW);
- if(getgdesc(GD_BITS_NORM_DBL_CMODE) < 12) {
- doingRGB = 1;
- RGBmode();
- }
- gconfig();
- initsort();
-
- /* fish story begins here */
- universe = bigBang(&univol, &voxvol);
-
- Expand(&usTemplate);
- Expand(&surfDieTemplate);
- Expand(&expanderTemplate);
- Expand(&advancerTemplate);
- Expand(&wigglerTemplate);
- Expand(&circlerTemplate);
- Expand(&swerverTemplate);
- Expand(&chameleonTemplate);
- Expand(&colorizerTemplate);
- Expand(&metamorphTemplate);
- Expand(&maleTemplate);
- Expand(&femaleTemplate);
- Expand(&feederTemplate);
- Expand(&wideyeTemplate);
- Expand(&fullVoxels);
- Expand(&mPanelTemplate);
- Expand(&trailGhostTemplate);
- Expand(&faderTemplate);
- }
-
- /*
- * tic off the rendering clock
- */
- tic()
- {
- register individual *newone;
- register subscr *sentry, *nentry;
- register int i, j;
- point2df newhead;
- circlerVars *initCircler;
- swerverVars *initSwerver;
- metamorphVars *initMeta;
- extern mailbox fullVoxels;
- individual *newovum;
- static int lastun = 100;
- static int backlev[] = { 40, 60, 63, 70, 77, 80};
-
- /* us keeps track of everybody who wants to get "tic'd" off */
- us = &usTemplate;
-
- #define ICOUNT 1
- #ifdef LONELY
- #define MCOUNT 1 /* number of minnows */
- #define GCOUNT 1 /* number of guppies + minnows */
- #define SCOUNT 0 /* number of seaweeds */
- #else /* LONELY */
- #define MCOUNT 3 /* number of minnows */
- #define GCOUNT 5 /* number of guppies + minnows */
- #define SCOUNT 3 /* number of seaweeds */
- #endif /* LONELY */
-
- /* build many fish */
- for (i=ICOUNT; i<=GCOUNT; i++) {
- if (i<=MCOUNT)
- newone = (individual *)clone(&minnowTemplate);
- else
- newone = (individual *)clone(&guppyTemplate);
-
- /* clone the individual's model description; add it to us */
- Msg(newone, INIT, NOARG, NULL);
- subscrFcn(us, newone);
-
- newone->scale = (long)(0.43 * i) + 2;
-
- if (egg_flag && i <= MCOUNT) { /* minnows can reproduce now */
- if (i==ICOUNT) {
- subscrFcn(&maleTemplate, newone);
- } else {
- subscrFcn(&femaleTemplate, newone);
- }
- }
- if (egg_flag && i > MCOUNT) { /* guppies can reproduce now */
- if (i==MCOUNT+1) {
- subscrFcn(&maleTemplate, newone);
- } else {
- subscrFcn(&femaleTemplate, newone);
- }
- }
-
- if (feed_flag && i <= MCOUNT) { /* minnows can eat now */
- subscrFcn(&feederTemplate, newone);
- }
-
- if (ghost_flag && i == 1) {
- subscrFcn(&trailGhostTemplate, newone);
- }
-
- /* behavior messages will happen from head to tail of subscr list */
- subscrFcn(&wigglerTemplate, newone);
- ((wigglerVars *)findvars(newone,WIGGLER))->wiggleClock = 7 * i;
-
- subscrFcn(&swerverTemplate, newone);
- /****
- initSwerver = (swerverVars *)findvars(newone,SWERVER);
- initSwerver->maxvelocity.x = 50 + (10 * i);
- initSwerver->maxvelocity.y = 70 + (8 * i);
- initSwerver->maxvelocity.z = 20 + (2 * i);
- ******/
- newone->position.x = 100 * i * (odd(i) ? 1 : -1);
- newone->position.y = 200 * i * (odd(i>>1) ? 1 : -1);
- newone->position.z = 100 * i * (odd(i>>1) ? -1 : 1);
- #ifdef LONELY
- newone->speed = 20.0 * i;
- newone->heading.x = 1.0;
- newone->heading.y = 0.0;
- newone->heading.z = 0.0;
- normalize(&newone->heading.x);
- bullet = TRUE; /* draw axes to see space more clearly */
- #else /* LONELY */
- newone->speed += (14 * i);
- newone->heading.x *= (odd(i) ? 1 : -1);
- newone->heading.y *= (odd(i>>1) ? 1 : -1);
- newone->heading.z *= (odd(i) ? 1 : -1);
- normalize(&newone->heading.x);
- #endif /* LONELY */
-
- if (! egg_flag)
- newVoxPosition(universe, &newone->position, newone);
-
- if (egg_flag) {
- newovum = (individual *)clone(&eggTemplate);
- subscribe(&metamorphTemplate, newovum);
- initMeta = (metamorphVars *)newovum->them.subscribedTo;
- initMeta->embryo = newone;
- initMeta->alarm = 20 * i;
- newovum->position = newone->position;
- newVoxPosition(universe, &newovum->position, newovum);
- subscribe(us, newovum);
- Msg(newovum, INIT, 0, NULL);
- }
- } /* for i */
-
- /* last guppy is a colorizer */
- if (newone) {
- subscrFcn(&colorizerTemplate, newone);
- }
-
- if (bub_flag) {
- /* build bubbles */
- newone = (individual *)clone(&bubbleMachineTemplate);
- Msg(newone, INIT, NOARG, NULL);
- subscribe(us, newone);
- }
-
- /* initialize toadStone */
- if(toad_flag) {
- newone = (individual *)clone(&toadTemplate);
- Msg(newone, INIT, NOARG, NULL);
- subscribe(us, newone);
- }
-
- if (landscape) {
- /* build seaweeds */
- for (i=1, j=1; i<=SCOUNT; i++) {
- newone = (individual *)clone(&seaTemplate);
- j = -j;
- ((sea *)newone)->length += j*(-10);
- Msg(newone, INIT, sizeof(point), &univol);
- newone->position.y *= j;
- if (i==1)
- newone->rotation.z += 450;
- if (i==3) {
- newone->position.x = -1500;
- newone->position.y = -3500;
- }
- subscribe(us, newone);
- }
- /* build a floor of pebbles */
- newone = (individual *)clone(&pebbleTemplate);
- Msg(newone, INIT, sizeof(point), &univol);
- subscribe(us, newone);
- }
-
- /* build a camera and control panel */
- theCamera = (camera *)clone(&cameraTemplate);
- Msg(theCamera, INIT, NOARG, NULL);
- thePanel = &mPanelTemplate;
-
- saveClock = ftime (&tb_start);/* so we don't get wigged out first timings */
-
- while(1) {
- masterClock++;
- /* setup for this rendering cycle */
- Msg(theCamera, POLL, NOARG, NULL);
- Msg(theCamera, TAKE, NOARG, NULL);
-
- viewport(0,curWindow.y, 0,curWindow.y);
- backface(TRUE);
-
- if(doingRGB) /* in rgb mode we can't cheat */
- dobackground = 3;
- if (dobackground) {
- fishWritemask(BACKGROUND);
- }
- else {
- fishWritemask(FOREGROUND);
- }
-
- fishColor(WATER_COLOR);
- clear();
-
- if (unsophistication >= 90)
- drawBowl();
-
- if (lastun != unsophistication) {
- for (i=0; i < (sizeof(backlev)/sizeof(int)); i++) {
- if (((lastun < backlev[i]) && (unsophistication >= backlev[i])) ||
- ((lastun > backlev[i]) && (unsophistication <= backlev[i]))) {
- dobackground = 3;
- }
- }
- lastun = unsophistication;
- }
-
- if (quit)
- return;
-
- /* advance the fish story */
- pushmatrix();
-
- if (bullet)
- drawOrig(); /* */
-
- /* update and compile each individual */
- numgups = 0;
- for (sentry = nentry = us->them.subscribers; nentry; sentry = nentry) {
- nentry = sentry->next;
- if(isSuper(sentry->member,GUPPY) ||
- isSuper(sentry->member,EGG)) numgups++;
- pushmatrix();
- Msg(sentry->member, DOIT, INSTARG, us);
- popmatrix();
- }
- #ifdef VOX_DEBUG
- /* debug */
- for (sentry=fullVoxels.subscribers; sentry; sentry = sentry->next) {
- drawVoxel(sentry->member);
- }
- #endif /* VOX_DEBUG */
- sortobjs(us);
- /* render each guppy from its compiled history */
- callobj((Object)us);
- /* done with this rendering cycle */
- popmatrix();
-
- /* draw other viewport for control panel */
- pushviewport();
- viewport(curWindow.y,curWindow.x, 0,curWindow.y);
- fishWritemask(FOREGROUND);
- fishColor(WATER_COLOR);
- clear();
-
- if (controls) {
- pushmatrix();
- ortho2(0.0,256.0, 767.0,0.0);
- backface(FALSE);
- drawControls(thePanel);
- callobj((Object)thePanel);
- popmatrix();
- }
- popviewport();
-
- swapbuffers();
-
- newClock = ftime (&tb_end);
- if (dobackground>0) dobackground--;
- /* HACK: if we get too slow, start over */
- if (timeit) {
- display_time ("main loop", masterClock, 1);
- }
- if ((newClock - saveClock > 120) || (fishPop <= 0) || numgups <= 0) {
- #ifdef TIMEOUT
- #define TIMEOUT
- return;
- #endif /* TIMEOUT */
- }
- saveClock = ftime (&tb_start);
- /* END HACK: if we get too slow, start over */
- #ifdef FUNNY_MALLOC
- while(!getbutton(PADENTER));
- if(maldbug){ long a,f,ac,fc;
- malloc_stats(&a,&f,&ac,&fc); /***/
- printf("allocated = %d\tfreed = %d\ta_cells =%d\tf_cells =%d\n",a,f,ac,fc); /***/
- }
- #endif /* FUNNY_MALLOC */
- #define FUNNY_MALLOC
- }
- }
-
-